using System;
using NUnit.Framework;
using WWB.DisqusSharp.Infrastructure.HammockWrappers;
using WWB.DisqusSharp.Model.DisqusService;
using WWB.DisqusSharp.Tests.TestUtility;

namespace WWB.DisqusSharp.Tests.DisqusServiceTests
{
    [Explicit("Don't want to hit service repeatedly.")]
    [TestFixture]
    [Category("Integration Tests")]
    public class DisqusForumServiceTests
    {
        private string threadId;
        private string forumId;
        private string user_api_key;
        private IDisqusForumService theService;

        [TestFixtureSetUp]
        public void ArrangeAndAct()
        {
            var ts = TestSettingsProvider.GetTestSettings();
            threadId = ts.ThreadId;
            forumId = ts.ForumId;
            user_api_key = ts.ApiKey;
            var ds = new HammockDisqusService(user_api_key);
            theService = ds.GetForumApi(forumId);
        }

        [Test]
        public void UpateThread_works()
        {
            var dt = DateTime.Now;
            string url = "http://www.example.com/disqussharp/" + dt.ToFileTime().ToString(); 
            string dateStamp = dt.ToString("s");
            var args = new UpdateThreadArgs()
                           {
                               AllowComments = true,
                               Slug = "Updated at " + dateStamp,
                               Title = "Updated at " + dateStamp,
                               Url = url
                           };
            var ret = theService.UpdateThread(threadId, args);
            Assert.That(ret, Is.Not.Null);                     
        }

        [Test]
        public void CreatePost_works()
        {
            var dt = DateTime.Now;

            var args = new CreatePostArgs(threadId, "Test from DisqusForumServiceTests sent at " + dt.ToString(),
                                          "nunit", "nunit@example.com");

            var ret = theService.CreatePost(args);

            Assert.That(ret, Is.Not.Null);

            Assert.That(ret.IsSuccessful, "Should be successful.");
            Assert.That(ret.Error, Is.Null, (ret.Error ?? ServiceError.NoError).ToString());
            Assert.That(ret.Payload.Id, Is.Not.Null);
            Assert.That(ret.Payload.IsAnonymous, "Should be anonomous");
            Assert.That(ret.Payload.AnonymousAuthor.Named, Is.EqualTo("nunit"));
        }

        [Test]
        public void ThreadByUrl_works()
        {
            var uid = DateTime.Now.ToFileTimeUtc().ToString();
            var args = new UpdateThreadArgs()
                           {
                               AllowComments = false,
                               Slug = "test_thread_" + uid,
                               Title = "zzzzzzzzzzGET THREAD BY URL TEST TRHEAD",
                               Url = "http://www.example.com/postsharp_getthreadbyurl_test"
                           };
            theService.UpdateThread(threadId, args);

            var ret = theService.ThreadByUrl(args.Url);

            Assert.That(ret, Is.Not.Null);
            Assert.That(ret.IsSuccessful, "Should be successful");

            Assert.That(ret.Payload.Url, Is.EqualTo(args.Url));
        }

        [Test]
        public void ThreadByIdentifier_works_for_existing_thread()
        {
            var args = new UpdateThreadArgs()
                           {
                               AllowComments = false,
                               Slug = "test_thread_" + DateTime.Now.ToFileTimeUtc().ToString(),
                               Title = "zzzzzzzzzzGET THREAD BY URL TEST TRHEAD",
                               Url = "http://www.example.com/postsharp_getthreadbyidentifier_works"
                           };
            theService.UpdateThread(threadId, args);

            var ret = theService.ThreadByIdentifier(threadId, args.Title, null, true);

            Assert.That(ret, Is.Not.Null);
            Assert.That(ret.IsSuccessful, "Error was type '" + (ret.Error ?? new ServiceError("", "")).Code + "' with message '" + (ret.Error ?? new ServiceError("", "")).Message + "'.");

            Assert.That(ret.Payload.Created, Is.False, "Should not be newly created.");
            Assert.That(ret.Payload.Thread.Title, Is.EqualTo(args.Title));
            Assert.That(ret.Payload.Thread.Identifier, Is.EqualTo(threadId));
        }

        [Test]
        public void ThreadByIdentifier_works_for_new_thread_with_create()
        {
            var ts = DateTime.Now.ToFileTimeUtc().ToString();
            var ret = theService.ThreadByIdentifier(ts, "Thread created for tests at " + ts, null, true);

            Assert.That(ret, Is.Not.Null);
            Assert.That(ret.Error, Is.Null, (ret.Error ?? new ServiceError("","")).ToString());
            Assert.That(ret.Payload.Created, "Should be newly created.");
            Assert.That(ret.Payload.Thread.Title, Contains.Substring(ts));

        }

        [Test]
        public void Moderation_works()
        {
            var originalPost =
                theService.CreatePost(new CreatePostArgs(threadId, "Test To Be Moderated",
                                                           "disqussharp-tests", "disqussharp-tests@example.org"))
                    .IsSuccessfulResult()
                    .WithPayload();

            var moderated = theService.ModeratePost(originalPost.Id, "kill")
                .IsSuccessfulResult()
                .WithPayload();

            Assert.That(moderated.Shown, Is.False);
        }

    }
}